/*
 * @Description: 公用方法
 * @Author: zhanyinjia
 * @Date: 2022-12-02 10:04:34
 * @LastEditors: zhanyinjia
 * @LastEditTime: 2023-05-22 11:26:09
 */
import _ from 'lodash'
/**
 * @description: 计算table单元格合并
 * @param {*} flatlist  平铺数组
 * @param {*} mergesDeps   合并计算所依赖的属性，按依赖范围从大到小排列，如：['orderId', 'materialId', 'outOrderId'...]，首先按照orderId合并，在orderId相同的情况下再按照materialId合并，以此类推;
 * @param {*} mergeColumns 各个需要合并的项依赖哪一级mergesDeps元素的映射关系;
 * @return {*}
 * @author: zhanyinjia
 */
/* 
示例参数：
{
  flatlist:[...],
  mergesDeps :['orderId', 'materialId', 'outOrderId'], 
  mergeColumns :{
    0: ['orderNo', 'saleDate', 'orderRemark', 'EBSCode'],  //这几项的合并计算依赖mergesDeps[0]（即orderId）的数据值是否相同；
    1: ['materialName', 'K3Code', 'receiveNumTotal', 'backNum'],   //这几项的合并计算依赖mergesDeps[1]（即materialId）的数据值是否相同；
    2: ['outOrderNo', 'unitPrice', 'payedNum']   //这几项的合并计算依赖mergesDeps[2]（即outOrderId）的数据值是否相同；
  } 
}
*/
const calculateMerges = (flatlist, { mergesDeps = null, mergeColumns = null } = {}) => {
  if (!mergesDeps || !mergeColumns) return flatlist
  const totalColumns = []
  for (const k in mergeColumns) {
    totalColumns.push(...mergeColumns[k])
  }
  const countPos = mergesDeps.reduce((p) => {
    p.push(0)
    return p
  }, [])
  flatlist.forEach((v, index) => {
    if (index == 0) {
      // 第1条数据
      totalColumns.forEach((key) => {
        v[`${key}-merge`] = {
          rowspan: 1,
          colspan: 1
        }
      })
    } else {
      let prevLevelIsSame = true
      for (let level = 0; level < mergesDeps.length; level++) {
        if (!prevLevelIsSame) break
        const key = mergesDeps[level]
        if (v[key] == flatlist[index - 1][key]) {
          prevLevelIsSame = true
          mergeColumns[level].forEach((m) => {
            flatlist[countPos[level]][`${m}-merge`].rowspan++
            v[`${m}-merge`] = {
              rowspan: 0,
              colspan: 0
            }
          })
        } else {
          prevLevelIsSame = false
          countPos[level] = index
          for (const k in mergeColumns) {
            if (k >= level) {
              countPos[k] = index
              mergeColumns[k].forEach((m) => {
                v[`${m}-merge`] = {
                  rowspan: 1,
                  colspan: 1
                }
              })
            }
          }
        }
      }
    }
  })
  return flatlist
}

/**
 * @description: 嵌套数据进行平铺，内外层相同的key名会改写以防止被覆盖
 * @param {*} data   原数组，如：[{name:'x',listA:[{name:'y',age:'z',listB:[{name:'j',sex:'k'}...]}...]}...]
 * @param {*} rules  原数组嵌套的结构，如：'listA.listB'
 * @return {*}  [{name:'x','listA-name':'y',age:'z','listB-name':'j',sex:'k'...}]
 * @author: zhanyinjia
 */
const nest2flat = (data, rules = '') => {
  if (!rules) return data
  const levels = rules.split('.')
  return flatFn(data, levels)
}

const flatFn = (data, [key, ...rest], duplicatePrefix = '', merge = {}) => {
  return data.reduce((prev, next) => {
    const itemCopy = _.cloneDeep(next)
    delete itemCopy[key]
    // 查询是否有和外层属性相同的key名，如果有重复，需要重命名key名
    const mergeKeys = Object.keys(merge)
    const itemCopyKeys = Object.keys(itemCopy)
    const intersection = _.intersection(mergeKeys, itemCopyKeys)
    intersection.forEach((key) => {
      itemCopy[`${duplicatePrefix}-${key}`] = itemCopy[key]
      delete itemCopy[key]
    })
    let subFlat = Object.assign(itemCopy, merge)
    if (key) {
      subFlat = flatFn(next[key], rest, key, itemCopy)
    } else {
      subFlat = [itemCopy]
    }
    prev.push(...subFlat)

    return prev
  }, [])
}

export { calculateMerges, nest2flat }
